﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ItemsViewBinding.cs" company="">
//   
// </copyright>
// <summary>
//   The items view binding.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Libium.Bindings
{
    using Libium.UseCases;
    using Libium.Views;

    /// <summary>
    /// The items view binding.
    /// </summary>
    /// <typeparam name="TUseCase">
    /// </typeparam>
    /// <typeparam name="TView">
    /// </typeparam>
    public class ItemsViewBinding<TUseCase, TView> : UseCaseBinding<TUseCase, TView>
        where TUseCase : IItemsUseCase
        where TView : IItemsView
    {
        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ItemsViewBinding{TUseCase,TView}"/> class.
        /// </summary>
        /// <param name="service">
        /// The service. 
        /// </param>
        /// <param name="useCase">
        /// The use case. 
        /// </param>
        /// <param name="view">
        /// The view. 
        /// </param>
        public ItemsViewBinding(IBindService service, TUseCase useCase, TView view)
            : base(service, useCase, view)
        {
        }

        #endregion

        #region Public Methods and Operators

        /// <summary>
        ///   The bind.
        /// </summary>
        public override void Bind()
        {
            base.Bind();
            foreach (var item in UseCase.Items)
            {
                BindItem(item, View);
            }

            UseCase.ItemAdded += (uc, i) => BindItem(i, View);
            // UseCase.ItemDeleted += (uc, i) => UnbindItem(i, View);
        }

        #endregion

        #region Methods

        /// <summary>
        /// The add item view.
        /// </summary>
        /// <param name="item">
        /// The item. 
        /// </param>
        /// <param name="view">
        /// The view. 
        /// </param>
        /// <returns>
        /// The <see cref="object"/> . 
        /// </returns>
        protected virtual object AddItemView(ItemsUseCaseItem item, TView view)
        {
            return view.AddItemView(item.TypeName);
        }

        /// <summary>
        /// The bind item.
        /// </summary>
        /// <param name="item">
        /// The item. 
        /// </param>
        /// <param name="view">
        /// The view. 
        /// </param>
        protected virtual void BindItem(ItemsUseCaseItem item, TView view)
        {
            var itemView = AddItemView(item, view);
            Bind(item.UseCase, itemView);

            // TODO Try to remove
            item.UseCase.Unavailable += (uc) => UnbindItem(item, itemView, view);
        }

        /// <summary>
        /// The unbind item.
        /// </summary>
        /// <param name="item">
        /// The item. 
        /// </param>
        /// <param name="itemView">
        /// The item view. 
        /// </param>
        /// <param name="view">
        /// The view. 
        /// </param>
        protected virtual void UnbindItem(ItemsUseCaseItem item, object itemView, TView view)
        {
            Unbind(item.UseCase, itemView);
            view.DeleteItemView(itemView);
        }

        #endregion
    }
}